The present invention relates to computer programming, and deals more particularly with techniques for compilers to generate code involving data that is not constant, but is unlikely to change except in relatively infrequent situations.
A compiler may alter or manipulate the assembly language code it generates in an attempt to optimize aspects of the application, such as its run-time performance. Such compilers are referred to as optimizing compilers, and are known in the art. One example is the Java™ Just-In-Time (“JIT”) compiler. (“Java” is a trademark of Sun Microsystems, Inc.)
A number of the variables used in a particular application program may actually have constant values across a particular execution of the program, or the values may change only very infrequently. Such variables are commonly called “glacial constants”. An example of such a value is a variable indicating whether tracing or debugging has been enabled: usually such functionality is disabled, unless a problem occurs. Accordingly, although compare-and-branch logic is provided in the compiled application to account for possible differing values of the variable, a majority of run-time behavior exercises a single destination for these branches.
Because the value of a glacial constant might change during the program's execution, existing compilers rarely do much to optimize uses of these variables. One known optimization is to generate specialized code for particular values of the variable, controlled by an “if” statement. If the specialized code is faster than the general code, then the cost of the “if” statement (e.g., accessing and loading a value, performing a comparison with the value, and branching on the comparison result) might be acceptable. However, the “if” statement does introduce a branch into the code that the processor will have to correctly predict to achieve the highest run-time performance. That branch occupies a slot in the processor branch history table that could be used to predict other branches in the application. This use of a branch prediction slot for branches determined by variables that act as glacial constants (and are thus easily predicted) therefore reduces the effectiveness of the processor's branch prediction resources.
Another specialization that might be possible is if the glacial constant is used to control an “if” statement itself. See, for example, the pseudocode sample in FIG. 1, where the variable “tracingEnabled” is a Boolean indicating whether tracing has been enabled for the executing code. Such statements cannot be optimized in the above way, however, because the “if” statement is already the test for the right values of the constant.